/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MOs.strategy.finiteDifference.BLO;

import MOs.strategy.finiteDifference.bean.*;
import MOs.strategy.finiteDifference.DAO.*;
import controller.java.Petri;
import data.java.Defs;

/**
 *
 * @author Erick Rubio Mendoza
 */
public class finiteDifferenceRulesBLO {
    
    //********************************************
    // MO Status Type
    //********************************************
    
    public static boolean isKing(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){
        Petri petri = Petri.getInstance();        
        if ((oFDMO.getNeighborsFriends()==8) && (oFDMO.getNeighborsEnemies()==0) && (petri.getNutrient(oFDMO.getX(),oFDMO.getY())>(oFDEnviroment.getMeanNutrients()+oFDEnviroment.getMaxNutrients())/2))
        {
            return true;
        }
        else
        {
            return false;
        }                
    }
    
    public static boolean isVIP(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){
        Petri petri = Petri.getInstance();        
        if (oFDMO.getNeighborsFriends()>oFDMO.getNeighborsEnemies() && oFDMO.getNeighborsEnemies()>0 && petri.getNutrient(oFDMO.getX(),oFDMO.getY())>(oFDEnviroment.getMeanNutrients()+oFDEnviroment.getMaxNutrients())/2)
        {
            return true;
        }
        else
        {
            return false;
        } 
    }
    
    public static boolean isSpecialForces(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){
        Petri petri = Petri.getInstance(); 
                  
        finiteDifferenceMO oFDMONeighbor = new finiteDifferenceMO();
        
        finiteDifferenceMODAO oFDDAO = new finiteDifferenceMODAO();
        boolean blnFoundVIPKing = false;
        
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                if (i!=0 && j!=0 && petri.inDish(oFDMO.getX()+i, oFDMO.getY()+j))
                {    
                    oFDMONeighbor.setX(oFDMO.getX()+i);
                    oFDMONeighbor.setY(oFDMO.getY()+j);
                    //oFDDAO.MOAnalysis(oFDMONeighbor);
                    
                    if (isKing(oFDMONeighbor,oFDEnviroment) || isVIP(oFDMONeighbor,oFDEnviroment)) 
                    {
                        blnFoundVIPKing=true;
                        break;
                    }
   
                }   
            }
        }
        if (blnFoundVIPKing==true)
        {
            return true;
        }
        else
        {
            return false;
        }
        
    }
    
    public static boolean isSecurity(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){
        Petri petri = Petri.getInstance();        
        if (oFDMO.getNeighborsFriends()>=oFDMO.getNeighborsEnemies() && petri.getNutrient(oFDMO.getX(),oFDMO.getY())>oFDEnviroment.getMeanNutrients() && petri.getNutrient(oFDMO.getX(),oFDMO.getY())<=(oFDEnviroment.getMeanNutrients()+oFDEnviroment.getMaxNutrients())/2)
        {
            return true;
        }
        else
        {
            return false;
        } 
    }
    
    public static boolean isCitizen(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){       
        if (oFDMO.getNeighborsFriends()>=oFDMO.getNeighborsEnemies())
        {
            return true;
        }
        else
        {
            return false;
        } 
    }    
    
    public static boolean isHostage(finiteDifferenceMO oFDMO, finiteDifferenceEnviroment oFDEnviroment){
        if (oFDMO.getNeighborsFriends()<oFDMO.getNeighborsEnemies())
        {
            return true;
        }
        else
        {
            return false;
        } 
    }
    
    //********************************************
    // MO Rules Finite Difference Method
    //********************************************
    
    public static boolean permanencyCondition(finiteDifferenceMO oFDMO)
    {
        //This is the permanency condition by Finite Difference Method
        if (oFDMO.getNutrient() > Defs.LESS_LIVE/Defs.EAT_PERCENT)
        {
            return true;
        }
        else
        {
            return false; //Is necesary that MO can move to other position
        }
    }
    
    
    public static boolean attackCondition(finiteDifferenceMO oFDMO, finiteDifferenceMO oFDMOOpponent)
    {
        //This is the attack condition by Finite Difference Method
        
        if (oFDMOOpponent.getEne()< (oFDMO.getEne()))         
        {
            return true;
        }    
        else
        {
            return false;
        }    
        
        /*
        if (
                oFDMOOpponent.getEne()*(1 + Math.sqrt(1 + 4*0.075f)) 
                < 
                2*(oFDMO.getEne())
            )           
        {
            return true;
        }    
        else
        {
            return false;
        }         
        */
    }    
    
    
}
